<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        /* 

           1- 什么是闭包
                闭包是指函数与其周围的状态的组合。
           2- 防抖和节流的应用场景
            
           3- 防抖的实现-节流（大公司）--利用了闭包

        
        */
        /* 
          函数是一等公民--- 函数的使用非常的灵活-像是一个变量一样，
             可以把一个函数存入一个变量中，
             可以把一个函数作为另一个函数的返回值，bind (高阶函数)
             也可以把一个函数作为另一个函数参数（高阶函数 forEach()）
 
           
          纯函数 --纯函数与外部的关联应该都来源于函数参数
        
        */

        // 纯函数
        function sum(a, b) {
            return a + b;
        }

        sum(1, 2);

        let c = 2;

        // 不纯
        function test(a) {
            return a + c;
        }

        /*
        #### 什么是闭包
    *****闭包是指函数与其周围的状态的组合。

这个环境包含了在函数声明时所能访问的所有变量和参数，
并且在函数执行过程中始终存在。
在JavaScript中，每当一个函数被创建时，就会创建一个新的词法环境。这个词法环境包含了函数中使用的所有变量和参数。如果这个函数返回一个函数，则返回的函数将持有这个词法环境，也就是说，它可以访问在父函数中定义的所有变量和参数。这种函数就称为闭包。



闭包 的官方解释 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
        
        */

        /* 
        
                 概念 ：闭包是指函数(box中return 的函数)与其周围的状态（局部变量a）的组合。
     
                 写法：
                    // 0-定一个函数
                    // 1-函数定义一个局部变量
                    // 2-函数返回要给新函数-新函数使用局部变量
                 作用：让局部变量常驻内存--产生私有变量
                        缺点：容易产生内存泄漏(不使用闭包的时候将全局的引用赋值null)
                 
                 其他辅助装
                    ：全局变量会一直常驻内存
                    : ****局部变量 函数执行期间有效（局部变量在使用完成 以后 会被内存销毁）

                     
                    垃圾回收机制--负责销毁垃圾--- 
                        算法：1-老的-引用计数  
                             2-新的--标记清除-- 所有从全局能引用到（访问）的变量都不会被当做垃圾，反之会被当做垃圾 回收了
        */

        function box() {
            // 1-定义一个局部变量
            let a = 1;
            // 2-返回要给新函数-新函数使用局部变量
            return function () {
                a++;
                // console.log(a);
                return a;
            }
        }

        // fn 就是 box 内返回的函数
        /* 
            fn = function () {
                a++;
                console.log(a);
            }
        */
        /*
            闭包的产生的原因
                全局中fn引用--box内部定义的函数，
                内部函数引用了句变量，导致  局部变量，被全局引用 --局部变量就不会被回收（因为垃圾回收机制）
        */
        var fn = box();
        var r = fn()
        console.log(r);
        setTimeout(() => {
            var r2 = fn()
            console.log(r2);
            fn = null
        }, 1000);



        // var fn2 = box();




        // var a = 1;
        // console.log(a);

        // setTimeout(() => {
        //     console.log(a);
        // }, 1000);

        // function fn(t) {
        //     var c = t;
        //     console.log(c);
        // }
        // fn(10)
        // fn(100)

    </script>

</body>

</html>